package com.coocaa.ops.admin.v1.auth.sys.provider.impl;

import com.coocaa.ops.admin.async.log.service.LogRecordServiceImpl;
import com.coocaa.ops.admin.base.properties.SystemProperties;
import com.coocaa.ops.admin.v1.auth.sys.biz.ISysUserBiz;
import com.coocaa.ops.admin.v1.auth.sys.biz.ISysUserRoleBiz;
import com.coocaa.ops.admin.v1.auth.sys.constant.LoginStatus;
import com.coocaa.ops.admin.v1.auth.sys.provider.ILdapLoginService;
import com.coocaa.ops.common.core.biz.auth.entity.SysUserEntity;
import com.coocaa.ops.common.core.biz.auth.entity.SysUserRoleEntity;
import com.coocaa.ops.common.tool.base.InstanceUtil;
import com.coocaa.ops.common.tool.http.HttpSessionUtil;
import com.coocaa.ops.common.tool.math.RandomUtil;
import com.coocaa.ops.admin.base.constant.SessionConstants;
import com.coocaa.ops.admin.v1.auth.sys.provider.ISysAuthorizeProvider;
import com.coocaa.ops.common.tool.md5.MD5Util;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author bijiahao
 * @date : 2019/3/27.
 * @description
 */
@Service
public class SysAuthorizeProviderImpl implements ISysAuthorizeProvider {
    @Autowired
    private ISysUserBiz sysUserBiz;
    @Autowired
    private ISysUserRoleBiz sysUserRoleBiz;
    @Autowired
    private LogRecordServiceImpl logRecordService;
    @Autowired
    private ILdapLoginService ldapLoginService;

    @Override
    public LoginStatus userLogin(HttpServletRequest request, HttpServletResponse response, String account, String ldapAccount, String pwd) throws Exception {
        SysUserEntity user = null;
        LoginStatus loginStatus;
        if (StringUtils.isNotBlank(ldapAccount)) {
            boolean isLoggedIn = ldapLoginService.validateUser(ldapAccount, pwd);
            if (isLoggedIn) {
                user = getOrAddNormalUserFromEmail(ldapAccount, pwd, SystemProperties.Constants.ENABLE_DEFAULT_ACCOUNT);
                if (user != null) {
                    loginStatus = LoginStatus.SUCCESS;
                } else {
                    loginStatus = LoginStatus.LDAP_ACCOUNT_NO_AUTHORITY;
                }
            } else {
                loginStatus = LoginStatus.WRONG_NAME_OR_PASSWORD;
            }
        } else {
            user = sysUserBiz.getUserByLoginName(account);
            if (user != null) {
                String md5PWD = MD5Util.md5(MD5Util.md5(pwd + user.getSalt()));
                if (!user.getLoginPwd().equals(md5PWD)) {
                    loginStatus = LoginStatus.WRONG_NAME_OR_PASSWORD;
                } else {
                    loginStatus = LoginStatus.SUCCESS;
                }
            } else {
                loginStatus = LoginStatus.WRONG_NAME_OR_PASSWORD;
            }
        }
        if (loginStatus == LoginStatus.SUCCESS) {
            List<Integer> finalDictList = InstanceUtil.newArrayList();
            // 查出用户所属业务组F
            List<Integer> dictList = Arrays.asList(sysUserBiz.listUserBusinessType(user.getId()));
            if (null != dictList) {
                finalDictList.addAll(dictList);
            }
            /**
             * -1标识不限的业务分类
             */
            finalDictList.add(-1);
            user.setDicts(finalDictList);
            //写入SESSION
            HttpSessionUtil.setSessionValue(request, SessionConstants.SESSION_LOGIN_USER, user);
            String loginIp = HttpSessionUtil.getIpAddr(request);
            String userAgent = request.getHeader("user-agent");
            logRecordService.logUserLoginRecord(user, loginIp, userAgent);
        }
        return loginStatus;
    }

    /**
     * 退出
     *
     * @param request
     * @param response
     */
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (SessionConstants.USER_INFO.equals(cookie.getName())) {
                    cookie.setMaxAge(0);
                    response.addCookie(cookie);
                    break;
                }
            }
        }
    }

    /*************** ===私有方法=== ********************* ===start=== ***************************************/

    private SysUserEntity getOrAddNormalUserFromEmail(String email, String password, boolean addDefaultUser) {
        SysUserEntity user = sysUserBiz.getUserByEmail(email);
        if (addDefaultUser && user == null) {
            // 本系统不存在该邮箱的账号时，新建
            // 默认登录名及用户名为邮箱用户名
            // 默认密码为域账号密码
            try {
                String salt = RandomUtil.getNum(6);
                String userName = email.split("@")[0];
                String loginName = userName;
                user = new SysUserEntity();
                user.setUserName(userName);
                user.setLoginName(loginName);
                user.setEmail(email);
                user.setLoginPwd(MD5Util.md5(MD5Util.md5(password + salt)));
                user.setSalt(salt);
                user.setDisabled(0);
                user.setSuperAdmin(0);
                sysUserBiz.add(user);
                handleSaveRoles(user, Arrays.asList(SystemProperties.Constants.DEFAULT_ROLES.split(",")));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
        }
        return user;
    }


    /**
     * 保存角色
     *
     * @param user
     * @param roles
     */
    private void handleSaveRoles(SysUserEntity user, List<String> roles) {
        List<SysUserRoleEntity> roleEntities = new ArrayList();
        List<Integer> roleIds = new ArrayList();
        for (String role : roles) {
            Integer roleId;
            SysUserRoleEntity entity = new SysUserRoleEntity();
            try {
                roleId = Integer.parseInt(role);
                entity.setUserId(user.getId());
                entity.setRoleId(roleId);
                roleEntities.add(entity);
                roleIds.add(roleId);
            } catch (NumberFormatException e) {
                //角色id字符转数字错误时，不添加入列表
            }
        }
        if (CollectionUtils.isNotEmpty(roleEntities)) {
            sysUserRoleBiz.getMapper().addBatch(roleEntities);
            user.setRoles(roleIds);
        }
    }
}
